// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   ObjectToObjectConverter.java

package org.springframework.core.convert.support;

import java.lang.reflect.*;
import java.util.Collections;
import java.util.Set;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;

final class ObjectToObjectConverter
	implements ConditionalGenericConverter
{

	ObjectToObjectConverter()
	{
	}

	public Set getConvertibleTypes()
	{
		return Collections.singleton(new org.springframework.core.convert.converter.GenericConverter.ConvertiblePair(java/lang/Object, java/lang/Object));
	}

	public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType)
	{
		if (sourceType.getType().equals(targetType.getType()))
			return false;
		else
			return java/lang/String != targetType.getType() ? hasToMethodOrFactoryMethodOrConstructor(targetType.getType(), sourceType.getType()) : hasFactoryConstructor(java/lang/String, sourceType.getType());
	}

	public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType)
	{
		Class sourceClass;
		Class targetClass;
		if (source == null)
			return null;
		sourceClass = sourceType.getType();
		targetClass = targetType.getType();
		Method method;
		if (java/lang/String == targetClass)
			break MISSING_BLOCK_LABEL_55;
		method = getToMethod(targetClass, sourceClass);
		if (method == null)
			break MISSING_BLOCK_LABEL_55;
		ReflectionUtils.makeAccessible(method);
		return method.invoke(source, new Object[0]);
		method = getFactoryMethod(targetClass, sourceClass);
		if (method == null)
			break MISSING_BLOCK_LABEL_89;
		ReflectionUtils.makeAccessible(method);
		return method.invoke(null, new Object[] {
			source
		});
		Constructor constructor = getFactoryConstructor(targetClass, sourceClass);
		InvocationTargetException ex;
		if (constructor != null)
		{
			return constructor.newInstance(new Object[] {
				source
			});
		} else
		{
			String message = String.format("No to%3$s() method exists on %1$s, and no static valueOf/of/from(%1$s) method or %3$s(%1$s) constructor exists on %2$s.", new Object[] {
				sourceClass.getName(), targetClass.getName(), targetClass.getSimpleName()
			});
			throw new IllegalStateException(message);
		}
		ex;
		throw new ConversionFailedException(sourceType, targetType, source, ex.getTargetException());
		ex;
		throw new ConversionFailedException(sourceType, targetType, source, ex);
	}

	private static Method getToMethod(Class targetClass, Class sourceClass)
	{
		Method method = ClassUtils.getMethodIfAvailable(sourceClass, (new StringBuilder()).append("to").append(targetClass.getSimpleName()).toString(), new Class[0]);
		return method == null || !targetClass.equals(method.getReturnType()) ? null : method;
	}

	private static Method getFactoryMethod(Class targetClass, Class sourceClass)
	{
		Method method = ClassUtils.getStaticMethod(targetClass, "valueOf", new Class[] {
			sourceClass
		});
		if (method == null)
		{
			method = ClassUtils.getStaticMethod(targetClass, "of", new Class[] {
				sourceClass
			});
			if (method == null)
				method = ClassUtils.getStaticMethod(targetClass, "from", new Class[] {
					sourceClass
				});
		}
		return method;
	}

	private static Constructor getFactoryConstructor(Class targetClass, Class sourceClass)
	{
		return ClassUtils.getConstructorIfAvailable(targetClass, new Class[] {
			sourceClass
		});
	}

	private static boolean hasToMethodOrFactoryMethodOrConstructor(Class targetClass, Class sourceClass)
	{
		return hasToMethod(targetClass, sourceClass) || hasFactoryMethod(targetClass, sourceClass) || hasFactoryConstructor(targetClass, sourceClass);
	}

	static boolean hasToMethod(Class targetClass, Class sourceClass)
	{
		return getToMethod(targetClass, sourceClass) != null;
	}

	static boolean hasFactoryMethod(Class targetClass, Class sourceClass)
	{
		return getFactoryMethod(targetClass, sourceClass) != null;
	}

	static boolean hasFactoryConstructor(Class targetClass, Class sourceClass)
	{
		return getFactoryConstructor(targetClass, sourceClass) != null;
	}
}
